/*
 * LightweightlogObject.java   2009/03/17
 *
 * Copyright 2008 Web & Zen Multimedia, All rights reserved.
 * Use is subject to license terms.
 */
package it.wzm.lightweightlog;

import java.io.Serializable;
import java.util.Observable;
import java.util.Properties;

/**
 * Each object in the application extends LightweightlogObject which supplies a common set of utilities for 
 * the creation and lifecycle of Object. It implements Constant for sharing all default values among all extending objects. 
 * Implemented interfaces are Observable for communicating with our LogFactory and  Serializable for backing up and restore objects if necessary, particularly when fail occurs.</p>
 * <p>
 * Two constructors are available: one that take a name and a set of properties, and a default no-args one.  
 * </p>
 * <p>
 * The properties shared, with relative getter, by all the Log objects are:
 * <ul>
 * <li>name: each object in application has a unique name</li>
 * <li>properties: set of properties derived from dump.properties</li>
 * <li>status: is responsibility of extending classes to set its status in response of operation</li>
 * <li>serialize: tell if object can be serialized</li>
 * </ul>  
 * </p>
 * @author Leonardo Celati
 */
abstract class LightweightlogObject extends Observable implements Constant, Serializable {	
  
    /** As required by serialization */
	private static final long serialVersionUID = 670537810422302948L;
    /** Holder for status */
    private Status status;	
	/** Property holder */
	private final Properties p;
	/** name for this object */
	private final String name;
	/** serialize or not  */
	private boolean serialize;
	
	
	/**
	 * Default constructor
	 */
	public LightweightlogObject() {
		this.status=Status.OFF;
		this.p=null;
		this.name=null;
	}
	
	/**
	 * Construct an Log Object from a given set of properties
	 * @param p set of properties
	 */
	public LightweightlogObject(String name, Properties p) {
		// set basic properties
		this.p=p;
		this.name=name;
		
    	// serialize/deserialize object ?
    	try {
    		serialize = Boolean.parseBoolean(p.getProperty("dumper.serialize", "true"));
    	} catch (Exception e) {
    		serialize=DEFAULT_SERIALIZE;
    	}
		
	}
    
    /**
     * Get specific property from our properties set, return null if not found
     * @param name the key to look for
     * @return value of key (null if not present)
     */
    protected final String get(String name) {
        for (Object key : p.keySet()) {	
            if ( key != null && ((String)key).indexOf(Constant.PROP_ROOT + this.getName() + "." + name) > -1) {
                return ((String) p.get(key)).trim();
            }
        }
        // nothing found...
        return null;
    }
    
    /**
     * Getter for name
     * @return String
     */
    public String getName() {
        return name;
    }    
    
	/**
	 * Getter for properties
	 * @return the p
	 */
	protected final Properties getProperties() {
		return this.p;
	}

    /**
     * Set current status
     * @param status
     */
    protected void setStatus(Status status) {
    	// cannot set different status when we shutdown...
    	if (this.status==Status.SHUTDOWN)
    		return;
    	else 
    		this.status=status;
    }

	/**
	 * Getter for status
	 * @return the status
	 */
	public final Status getStatus() {
		return status;
	}
	
	/**
	 * Getter for serialization
	 * @return true/false
	 */
	public final boolean isSerializationActive() {
		return this.serialize;
	}
		
    /**
     * Overwriting the inherited method from Object
     * @return string representation of object
     */
    @Override
    public String toString() {
    	
    	// iterate, build then return a string
        StringBuilder sb = new StringBuilder();
    	
    	for (Object key: this.getProperties().keySet()) {
	        if (((String)key).indexOf(Constant.PROP_ROOT + this.getName() + ".") > -1) {
	            sb.append( "," +  ((String)key).replaceAll(Constant.PROP_ROOT + this.getName() + ".", "") + "=" +  p.get(key) );
	        }
	    } 	
    	// return...
        return super.toString() + " {hc=" + this.hashCode() + ",name=" + this.getName() + ",status=" + this.getStatus() + sb.toString() + "}" ;
    } 
	
    /**
     * Kill this object and free resources, developer can have his own
     * clean method by overridding this method
     */
    public void kill() {
    }
    
}
